<template>
    <xh-pages>
        <view class="pages-container">
            <view class="classify">
                <view>
                    <image :src="poster.icon" mode="scaleToFill" class="icon" />
                </view>
                <text class="title">{{ poster.classify_title }}</text>
                <text class="tips">{{ poster.tips }}</text>
            </view>
            <view class="role">
                <view class="role-bg">
                    <view class="role-item" v-for="(item, index) in poster.content">
                        <input class="role-input" v-model="item.value" :placeholder="getPlaceholder(item, index)"
                            placeholder-class="input-placeholder" />
                    </view>
                </view>
            </view>
            <view class="tips1">已有 {{ poster.browse }} 人生成情侣海报</view>
            <view class="btn" @tap="createPoster">
                <text class="text">开始生成CP海报</text>
            </view>
            <view class="flex flex-center">
                <text class="link py-4"
                    @tap="openWin({ url: '/pages/poster/posterList?id=' + poster.classify_id, type: 'redirectTo' })">更多CP海报</text>
            </view>
            <swiper class="swiper" :indicator-dots="false" :autoplay="false" :display-multiple-items="4"
                v-if="posterList.length > 0">
                <swiper-item v-for="item in posterList">
                    <view class="swiper-item uni-bg-red" @tap="selectedPoster(item)">
                        <view class="tag">
                            <text class="text vip" v-if="item.vip_state">VIP</text>
                            <text class="text" v-else>免费</text>
                        </view>
                        <image :src="item.url" mode="scaleToFill" class="swiper-poster" />
                    </view>
                </swiper-item>
            </swiper>
        </view>
        <u-popup :show="showPoster" @close="close" mode="center">
            <view>
                <!-- #ifdef H5 -->
                <image :src="posterData" class="poster" :style="{ height: posterHeight + 'px' }" mode="scaleToFill"
                    v-if="posterData" />
                <!-- #endif -->
                <canvas type="2d" class="poster" :style="{ height: posterHeight + 'px' }" canvas-id="poster" id="poster"
                    :class="{ 'd-none': posterData }"></canvas>
                <view class="btn" @tap="close">
                    <text class="text">重新生成</text>
                </view>
                <view class="tips1 pb-4">长按海报保存</view>
            </view>
        </u-popup>
    </xh-pages>
</template>
<script lang="ts" setup>
import { toast, openWin } from '@/utils/helpers';

interface contentItem {
    name: string;
    value: string;
    x: number;
    y: number;
    size: number;
    color: string;
    font: string;
    font_url?: string;
    bold: string;
    isHorizontal: boolean;
    isStroke: boolean;
}
const showPoster = ref(false);
let CanvasContext: any = null;
let canvas: any = null;
const poster = ref<{
    classify_title: string;
    icon: string;
    title: string;
    tips: string;
    url: string;
    classify_id?: number;
    browse: number;
    content: contentItem[]
}>({
    classify_title: '',
    icon: '',
    title: '',
    tips: '',
    url: '',
    browse: 0,
    content: []
})
const poster_id = ref('');
const posterData = ref('');
let fonts: {
    name: string;
    url: string;
}[] = [];
onReady(() => {
    // #ifdef H5
    CanvasContext = uni.createCanvasContext('poster');
    // #endif
})
onLoad((options: any) => {
    if (!options.id) {
        toast('参数错误');
        uni.navigateBack();
    }
    if (options.poster_id) {
        poster_id.value = options.poster_id;
    }
    getPoster(options.id);
    getPosterList(options.id);
})
const getPoster = (id: string) => {
    uni.$u.http.post('Poster/details', {
        classify_id: id,
        poster_id: poster_id.value
    }).then((res: any) => {
        if (res?.code == 200) {
            poster.value = res.data;
            poster_id.value = res.data.id;
            fonts = res.data.content.map((item: contentItem) => {
                return {
                    name: item.font,
                    url: item.font_url
                };
            });
            fonts = fonts.filter((item: any) => {
                return item.url;
            });
            // fonts去重
            fonts = fonts.reduce((prev: any, cur: any) => {
                const has = prev.find((item: any) => {
                    return item.name == cur.name;
                });
                if (!has) {
                    prev.push(cur);
                }
                return prev;
            }, []);
            loadFont();
        } else if (res?.code == 301) {
            toast(res?.msg ?? '网络错误')
            setTimeout(() => {
                openWin({ url: '/pages/users/index?t=1' }, 'reLaunch')
            }, 2000);
        } else {
            toast(res?.msg ?? '网络错误')
        }
    }).catch(() => {
        uni.navigateBack();
    })
}
const selectedPoster = (item: any) => {
    if (poster_id.value == item.id) {
        return;
    }
    poster_id.value = item.id;
    getPoster(item.classify_id);
}
const posterList = ref([]);
const getPosterList = (id: string) => {
    uni.$u.http.post('Poster/posterList', {
        classify_id: id
    }).then((res: any) => {
        if (res?.code == 200) {
            posterList.value = res.data;
        }
    })
}
const loadFont = () => {
    if (fonts.length > 0) {
        let font = fonts.shift();
        if (!font) {
            return;
        }

        let customFont = new FontFace(font.name, `url(${font.url}`);
        customFont.load().then(function (font) {
            document.fonts.add(font);
            loadFont();
        });
    }
}
const getPlaceholder = (item: contentItem, index: number) => {
    let str = item.name;
    if (!item.name) {
        str = '请输入角色' + (index + 1);
    }
    return str;
}
const drawImage = async (url: string, x: number, y: number, w: number, h: number) => {
    // #ifdef H5
    CanvasContext.drawImage(url, x, y, w, h);
    step.value++;
    draw();
    // #endif
}
const sInfo = uni.getSystemInfoSync();
const posterWidth = sInfo.windowWidth * 0.8;
const posterHeight = ref(posterWidth);
const step = ref(0);
let posterBgImg: HTMLImageElement;
// 缩放比例
let scale = 1;
const createPoster = () => {
    uni.showLoading({
        title: '生成中'
    })
    uni.$u.http.post('Poster/createPoster', {
        poster_id: poster_id.value,
        content: poster.value.content
    }).then((res: any) => {
        if (res?.code == 200) {
            posterBgImg = new Image();
            posterBgImg.src = res.data;
            posterBgImg.onload = () => {
                scale = posterWidth / posterBgImg.width;
                posterHeight.value = posterBgImg.height * scale;
            }
            posterData.value = res.data;
            showPoster.value = true;
            uni.hideLoading();
        } else {
            toast(res?.msg ?? '网络错误')
        }
    }).catch(() => {
        uni.hideLoading();
    })
}
const createPoster1 = () => {
    if (!poster_id.value) {
        toast('请选择海报');
        return;
    }
    const p = poster.value.content;
    for (let i = 0; i < p.length; i++) {
        const item = p[i];
        if (!item.value) {
            toast(getPlaceholder(item, i));
            return;
        }
    }
    showPoster.value = true;
    uni.showLoading({
        title: '生成中'
    })
    step.value = 0;
    draw();
}
const draw = () => {
    // 清除画布
    switch (step.value) {
        case 0:
            if (posterBgImg) {
                CanvasContext.clearRect(0, 0, posterWidth, posterHeight.value);
            }
            posterBgImg = new Image();
            posterBgImg.src = poster.value.url;
            posterBgImg.onload = () => {
                scale = posterWidth / posterBgImg.width;
                posterHeight.value = posterBgImg.height * scale;
                drawImage(poster.value.url, 0, 0, posterWidth, posterHeight.value);
                CanvasContext.save();
                step.value++;
                draw();
            }
            break;
        case 1:
            // 画文字
            poster.value.content.forEach((item: contentItem, index) => {
                CanvasContext.save();
                let font: string[] = [];
                if (item.bold) {
                    font.push(item.bold);
                }
                font.push(`${item.size}px`);
                font.push(item.font);
                CanvasContext.font = font.join(' ');
                let name = item.value;
                const x = item.x * scale;
                const y = item.y * scale;
                if (item.isHorizontal) {
                    if (item.isStroke) {
                        CanvasContext.strokeStyle = item.color;
                        CanvasContext.strokeText(name, x, y + item.size);
                    } else {
                        CanvasContext.fillStyle = item.color;
                        CanvasContext.fillText(name, x, y + item.size);
                    }
                } else {
                    let text = name.split('');
                    text.forEach((t, index) => {
                        if (item.isStroke) {
                            CanvasContext.strokeStyle = item.color;
                            CanvasContext.strokeText(t, x, y + item.size * index + 2);
                        } else {
                            CanvasContext.fillStyle = item.color;
                            CanvasContext.fillText(t, x, y + item.size * index + 2);
                        }
                    });
                }
                CanvasContext.restore();
            });
            step.value++;
            draw();
            break;
        case 2:
            console.log('绘制完成');
            // #ifdef H5
            CanvasContext.draw(false, () => {
                uni.hideLoading();
                saveImage();
            });
            // #endif
            break;
    }
}
const saveImage = () => {
    uni.canvasToTempFilePath({
        canvasId: 'poster',
        success: (res) => {
            posterData.value = res.tempFilePath;
        },
        fail: (err) => {
            console.log('错误', err);
            toast('海报生成失败，请重试')
        }
    })
}
const close = () => {
    showPoster.value = false
}
</script>
<style lang="scss" scoped>
.pages-container {
    background-image: url('@/static/pic_bg_youxi.png');
    background-size: 100% 100%;
    min-height: 100%;
}

.classify {
    padding: 40px 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    width: 60%;
    margin: 0 auto;
    text-align: center;

    .icon {
        width: 100px;
        height: 100px;
        border-radius: 10px;
        border: solid 1px #FFFFFF;
    }

    .title {
        font-size: 16px;
        font-weight: 500;
        color: #2A2C31;
        line-height: 19px;
        padding: 10px 0;
    }

    .tips {
        font-size: 13px;
        font-weight: 400;
        color: #969AAB;
        line-height: 15px;
    }
}

.role {
    display: flex;
    justify-content: center;
    align-items: center;
    background-image: url('@/static/pic_poster_role_bg.png');
    background-size: 100% 100%;

    .role-bg {
        width: 60%;
        min-height: 200px;
        display: flex;
        flex-direction: column;
        justify-content: space-around;
        align-items: center;
        padding: 20px;

        .role-item {
            width: 100%;

            .role-input {
                height: 40px;
                font-size: 14px;
                font-weight: 400;
                color: #C2A072;
                line-height: 40px;
                text-align: center;
            }

            .input-placeholder {
                height: 40px;
                font-size: 14px;
                font-weight: 400;
                color: #C2A072;
                line-height: 40px;
            }
        }
    }
}

.tips1 {
    font-size: 12px;
    font-weight: 400;
    color: #FF6997;
    line-height: 16px;
    text-align: center;
}

.btn {
    width: 80%;
    height: 52px;
    margin: 20px auto;
    background-image: url('@/static/btn_poster.png');
    background-size: 100% 100%;
    text-align: center;
    line-height: 40px;

    .text {
        font-size: 14px;
        font-weight: 500;
        color: #FFFFFF;
        line-height: 16px;
        text-shadow: 0px 1px 4px #E51852;
    }
}

.link {
    font-size: 12px;
    font-weight: 500;
    color: #FF6997;
    line-height: 16px;
    // 下划线
    text-decoration: underline;
}

.d-none {
    display: none;
}

.swiper {
    width: 80%;
    margin: 20px auto;
    height: 216rpx;

    .swiper-item {
        height: 204rpx;
        padding: 6rpx;
        position: relative;

        .swiper-poster {
            width: 100%;
            height: 100%;
            border-radius: 10px;
        }

        .tag {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            z-index: 100;

            .text {
                font-size: 12px;
                font-weight: 500;
                color: #FFFFFF;
                line-height: 16px;
                text-align: center;
                padding: 2px 10px;
                background-color: rgba(0, 0, 0, .5);
                border-radius: 10px;

                &.vip {
                    background-color: #FF6997;
                }
            }
        }
    }
}

.poster {
    width: 80vw;
}
</style>